package com.dure.hotmemory.scenes.tzxl;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.EmbossMaskFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.os.Build;


import com.dure.commonlib.util.PreferencesUtils;
import com.dure.hotmemory.R;
import com.dure.hotmemory.bean.Cell;
import com.dure.hotmemory.controllers.Controller;
import com.dure.hotmemory.drawview.BaseSurfaceView;
import com.dure.hotmemory.scenes.BaseScene;

import java.util.ArrayList;

/**
 * Created by leix on 8/31/16.
 */
public class GridMemoryScene extends BaseScene {

    private Paint paint;
    private int lineSize = 5;
    private int rowNumber = 3, columnNumber = 3;
    private int showNumber = 3;

    ArrayList<Cell> cellList = new ArrayList<>();
    ArrayList<Cell> randomCellList = new ArrayList<>();

    float frameLeft, frameTop;
    float frameWidth, frameHeight;
    private float cellSize;
    private float frameEdgeWidth;
    private float cellGap;

    private boolean canChoose;

    private Bitmap correctBitmap;

    private int rightNumber;
    private boolean dataPrepared;
    private RectF frameRectF;
    private boolean showNext = true;
    private long startShowTime, prepareNextTime, wrongShowTime, restartWaitTime;
    private boolean showTime, roundFinish, gameOver, restart, startDraw;
    private Cell wrongCell;
    private RectF rightBtnRectF, leftBtnRectF;
    private Bitmap heartBitmap;
    float topStateHeight;
    private int heartCount = 3;
    private String finishInfo;
    Controller controller;
    boolean newRecordGet;
    private  String alias;
    private EmbossMaskFilter emboss;
    int[] colors = {Color.WHITE, Color.parseColor("#00BDFF")};

    public GridMemoryScene(BaseSurfaceView baseSurfaceView) {
        super(baseSurfaceView);
        controller = new Controller(this);
        init();
    }


    public void init() {

        paint = new Paint();
        paint.setColor(Color.WHITE);
        paint.setAntiAlias(true);
        paint.setStrokeWidth(lineSize);

        cellSize = baseSurfaceView.getWidth() / 10f;
        frameEdgeWidth = cellSize / 5;
        cellGap = frameEdgeWidth / 2;

        correctBitmap = BitmapFactory.decodeResource(activity.getResources(), R.mipmap.correct);
        heartBitmap = BitmapFactory.decodeResource(activity.getResources(), R.mipmap.heart);
        topStateHeight = baseSurfaceView.getWidth() * 0.12f;
        alias = PreferencesUtils.getString(activity, "current_alias");

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
            float[] direction = new float[] { 1, 1, 1 };
            // 设置环境光亮度
            float light = 0.5f;
            // 选择要应用的反射等级
            float specular = 10;// 这个参数更改没有看出效果上面的变化
            // 向mask应用一定级别的模糊
            float blur = 3;// 这个参数可以控制立体侧面的宽度
            emboss = new EmbossMaskFilter(direction, light, specular, blur);
            paint.setMaskFilter(emboss);
        }
    }

    @Override
    public void handleData() {
        if (showNext) {
            showNext = false;
            rightNumber = 0;
            initCellData();
            dataPrepared = true;
            showTime = false;
            startShowTime = System.currentTimeMillis();
            startDraw = true;
        }

        if (!showTime && System.currentTimeMillis() - startShowTime > 1000) {
            showTime = true;
        }

        if (showTime && System.currentTimeMillis() - startShowTime > 2000) {
            showTime = false;
            canChoose = true;
        }

        if (wrongCell != null && System.currentTimeMillis() - wrongShowTime > 1000) {
            wrongCell.color = Color.GRAY;
            wrongCell = null;

            if (heartCount == 0) {
                finishInfo = "挑战失败，请再接再厉！";
                gameOver = true;
            }
        }

        if (roundFinish && System.currentTimeMillis() - prepareNextTime > 1000) {
            if (showNumber < 10)
                showNumber++;
            if (rowNumber == columnNumber) {
                if (rowNumber < 10)
                    rowNumber++;
            } else {
                if (columnNumber < 10)
                    columnNumber++;
            }

            roundFinish = false;
            showNext = true;
        }

        if (restart && System.currentTimeMillis() - restartWaitTime > 1000){
            restart = false;
            heartCount = columnNumber = rowNumber = showNumber = 3;
//            stepIndex = 0;
//            heartCount = 3;
//            pointNumber = 3;
            showNext = true;
        }
    }

    private void initCellData() {


        frameWidth = cellSize * columnNumber + 2 * frameEdgeWidth + (columnNumber - 1) * cellGap;
        frameHeight = cellSize * rowNumber + 2 * frameEdgeWidth + (rowNumber - 1) * cellGap;

        frameLeft = baseSurfaceView.getWidth() / 2 - frameWidth / 2;
        frameTop = baseSurfaceView.getHeight() / 2 - frameHeight / 2;
        frameRectF = new RectF(frameLeft, frameTop, frameLeft + frameWidth, frameTop + frameHeight);

        cellList.clear();

        for (int i = 0; i < rowNumber * columnNumber; i++) {
            int columnIndex = i % columnNumber;
            int rowIndex = i / columnNumber;
            float left = frameEdgeWidth + frameLeft + columnIndex * cellSize + columnIndex * cellGap;
            float top = frameEdgeWidth + frameTop + rowIndex * cellSize + rowIndex * cellGap;

            Cell cell = new Cell();
            PointF pointF = new PointF();
            pointF.x = left;
            pointF.y = top;
            cell.pointF = pointF;

            RectF rectF = new RectF(left, top, left + cellSize, top + cellSize);

            cell.rectF = rectF;
            cellList.add(cell);
            cell.color = Color.GRAY;
        }

        randomCellList.clear();
        while (cellList.size() > 0 && randomCellList.size() < showNumber) {// 随机选中showNumber个cell来显示
            int index = (int) (Math.random() * (columnNumber * rowNumber));
            Cell cell = cellList.get(index);
            if (!cell.active) {
                cell.active = true;
                randomCellList.add(cell);
                cell.color = Color.CYAN;
            }

        }
    }

    @Override
    public void handleDraw(Canvas canvas) {
        if (!dataPrepared)
            return;



        if (gameOver) {
            drawFinishDialog(canvas);
        }else if (startDraw){
            drawFrame(canvas);

            drawCells(canvas);

            drawHeart(canvas);

            drawScore(canvas);
        }

    }

    private void drawFrame(Canvas canvas) {
        paint.setColor(Color.BLACK);
        canvas.drawRect(frameRectF, paint);
    }

    private void drawCells(Canvas canvas) {

        for (int i = 0; i < cellList.size(); i++) {
            Cell cell = cellList.get(i);

            if (showTime) {
                if (cell.active)
                    paint.setColor(Color.CYAN);
                else {
                    paint.setColor(Color.GRAY);
                }
                canvas.drawRect(cell.rectF, paint);
            } else {
                if (!cell.show) {
                    paint.setColor(Color.GRAY);
                    canvas.drawRect(cell.rectF, paint);
                } else {
                    paint.setColor(cell.color);
                    canvas.drawRect(cell.rectF, paint);

                    if (cell.bitmap != null) {
                        Rect srcRect = new Rect(0, 0, cell.bitmap.getWidth(), cell.bitmap.getHeight());
                        canvas.drawBitmap(cell.bitmap, srcRect, cell.rectF, null);
                    }
                }


            }

        }
    }

    private void drawHeart(Canvas canvas) {
        Rect srcRect = new Rect(0, 0, heartBitmap.getWidth(), heartBitmap.getHeight());

        float dstHeartSize = topStateHeight * 0.8f;
        float leftPadding = topStateHeight * 0.2f;
        float topPadding = leftPadding;
        for (int i = 0; i < heartCount; i++) {
            float dstLeft = leftPadding * (i + 1) + i * dstHeartSize;
            float dstTop = topPadding;
            float dstRight = dstLeft + dstHeartSize;
            float dstBottom = dstTop + dstHeartSize;
            RectF dstRect = new RectF(dstLeft, dstTop, dstRight, dstBottom);

            canvas.drawBitmap(heartBitmap, srcRect, dstRect, null);
        }
    }

    private void drawScore(Canvas canvas) {
        String scoreStr = String.format("%d/%d", rightNumber, showNumber);
        String recordStr = String.format("Best:%d", PreferencesUtils.getInt(activity, alias + ":best", 0));

        float textSize = topStateHeight * 0.6f;
        paint.setTextSize(textSize);

        float scoreWidth = paint.measureText(scoreStr);
        float contentWidth = paint.measureText(recordStr);
        float rightPadding = topStateHeight * 0.2f;
        float topPadding = rightPadding;

        float contentLeft = canvas.getWidth() - rightPadding - contentWidth;
        float contentBottom = topPadding + textSize;

        paint.setColor(Color.WHITE);
        canvas.drawText(recordStr, contentLeft, contentBottom, paint);

        float scoreLeft = canvas.getWidth() / 2 - scoreWidth / 2;
        float scoreBottom = contentBottom;
        canvas.drawText(scoreStr, scoreLeft, scoreBottom, paint);
    }

    private void drawFinishDialog(Canvas canvas) {
        String infoStr = finishInfo;
        String exitStr = "退出";
        String continueStr = "重来";

        float dialogWidth = canvas.getWidth() * 0.8f;
        float dialogHeight = dialogWidth * 0.6f;
        float infoPartHeight = dialogHeight * 0.7f;
        float btnPartHeight = dialogHeight * 0.3f;

        float infoTextSize = dialogWidth * 0.8f / infoStr.length();

        // 绘制dialog frame
        float dialogLeft = canvas.getWidth() / 2 - dialogWidth / 2;
        float dialogTop = canvas.getHeight() / 2 - dialogHeight / 2;
        float dialogRight = canvas.getWidth() / 2 + dialogWidth / 2;
        float dialogBottom = canvas.getHeight() / 2 + dialogHeight / 2;
        RectF dialogRectF = new RectF(dialogLeft, dialogTop, dialogRight, dialogBottom);
        paint.setColor(Color.WHITE);
        float arc = dialogRectF.width() / 15;

        LinearGradient lg = new LinearGradient(dialogRectF.width() /2, 0, dialogRectF.width() /2, dialogRectF.height(), colors, null, Shader.TileMode.MIRROR);
        paint.setShader(lg);
        canvas.drawRoundRect(dialogRectF, arc, arc, paint);
        paint.setShader(null);

        // 绘制info
        paint.setTextSize(infoTextSize);
        float infoWidth = paint.measureText(infoStr);
        float infoLeft = canvas.getWidth() / 2 - infoWidth / 2;
        float infoBottom = dialogTop + infoPartHeight / 2 + infoTextSize / 2;
        paint.setColor(Color.RED);
        canvas.drawText(infoStr, infoLeft, infoBottom, paint);

        float btnWidth = dialogWidth * 0.3f;
        float btnHeight = btnWidth / 2.5f;
        float btnTextSize = btnHeight * 0.6f;

        // 绘制左边btn
        float leftBtnLeft = canvas.getWidth() / 2 - dialogWidth / 4 - btnWidth / 2;
        float leftBtnBottom = dialogBottom - btnPartHeight / 2 + btnHeight / 2;
        float leftBtnRight = leftBtnLeft + btnWidth;
        float leftBtnTop = leftBtnBottom - btnHeight;
        leftBtnRectF = new RectF(leftBtnLeft, leftBtnTop, leftBtnRight, leftBtnBottom);
        arc = leftBtnRectF.width() / 15;
        paint.setColor(Color.parseColor("#00BDFF"));
        canvas.drawRoundRect(leftBtnRectF, arc, arc, paint);

        paint.setTextSize(btnTextSize);
        float exitStrWidth = paint.measureText(exitStr);
        float exitLeft = leftBtnLeft + btnWidth / 2 - exitStrWidth / 2;
        float exitBottom = leftBtnBottom - btnHeight * 0.3f;
        paint.setColor(Color.WHITE);
        canvas.drawText(exitStr, exitLeft, exitBottom, paint);

        // 绘制右边btn
        float rightBtnLeft = canvas.getWidth() / 2 + dialogWidth / 4 - btnWidth / 2;
        float rightBtnBottom = leftBtnBottom;
        float rightBtnRight = rightBtnLeft + btnWidth;
        float rightBtnTop = leftBtnTop;
        rightBtnRectF = new RectF(rightBtnLeft, rightBtnTop, rightBtnRight, rightBtnBottom);
        arc = rightBtnRectF.width() / 15;
        paint.setColor(Color.parseColor("#00BDFF"));
        canvas.drawRoundRect(rightBtnRectF, arc, arc, paint);

        paint.setTextSize(btnTextSize);
        float continueStrWidth = paint.measureText(continueStr);
        float continueLeft = rightBtnLeft + btnWidth / 2 - continueStrWidth / 2;
        float continueBottom = rightBtnBottom - btnHeight * 0.3f;
        paint.setColor(Color.WHITE);
        canvas.drawText(continueStr, continueLeft, continueBottom, paint);
    }

    @Override
    public void handleDown(PointF pointF) {
        downX = pointF.x;
        downY = pointF.y;
    }

    float downX, downY;

    @Override
    public void handleUp(PointF pointF) {
        float upX = pointF.x;
        float upY = pointF.y;

        if (Math.abs(downX - upX) < 50
                && Math.abs(downY - upY) < 50) {// 视为点击
            isChooseRight(downX, downY);

        } else {// 视为拖动

        }
    }

    private void isChooseRight(float x, float y) {
        if (!canChoose) {
            return;
        }

        if (wrongCell != null)
            return;

        if (gameOver) {
            if (leftBtnRectF.contains(x, y)) {
                roundFinish = false;
                gameOver = false;
                activity.backToLastScene();
            } else if (rightBtnRectF.contains(x, y)) {
//                heartCount = columnNumber = rowNumber = showNumber = 3;
                restart = true;
                startDraw = false;
//                roundFinish = false;
                gameOver = false;
                restartWaitTime = System.currentTimeMillis();
//                showNext = true;
            }

        } else if (frameRectF.contains(x, y)) {// 先判断点击是否在frame内 如果点在frame内, 再判断点击是否正确

            for (int i = 0; i < cellList.size(); i++) {

                Cell cell = cellList.get(i);

                if (!cell.show && cell.rectF.contains(x, y)) {// 如果点击cell, 判断该cell是否是正确的

                    // 先判断此cell是否己被选择
                    cell.show = true;
                    cell.selected = true;
                    if (cell.active) {//正确
                        cell.isCorrect = true;
                        rightNumber++;

                        if (rightNumber == showNumber) {// 用户全部选对
                            cell.bitmap = correctBitmap;
                            canChoose = false;

                            int oldBest = PreferencesUtils.getInt(activity, alias + ":best", 0);
                            if (showNumber > oldBest) {
                                newRecordGet = true;
                                PreferencesUtils.putInt(activity, alias + ":best", showNumber);
                            }

                            prepareNextTime = System.currentTimeMillis();
                            roundFinish = true;

                        }
                    } else {
                        heartCount--;
                        cell.isCorrect = false;
                        cell.color = Color.RED;
                        wrongCell = cell;
                        wrongShowTime = System.currentTimeMillis();

                        canChoose = false;


                    }

                    break;
                }
            }
        }


    }

    @Override
    public void handleBack() {
        if (PreferencesUtils.getBoolean(activity, "login_success")){
            if (newRecordGet) {
                int level = PreferencesUtils.getInt(activity, alias + ":best", 0);
                controller.uploadTrainingData(String.valueOf(level), alias);
            }
        }
    }
}
